import React, { useState } from "react";
import showMessage from "../message";
import { useContext } from "react";
import $ from "jquery";
import { UserContext } from "../../../context/user/userContext";
import { ResetPassword } from "./../../../services/commonService";
import { getSubDomainName } from "../../../services/wrapperService";

export const ResetPasswordBox = (props) => {
  const { state } = useContext(UserContext);
  const [showError, setShowError] = useState(false);
  const [processing, setProcessing] = useState(false);
  const [errorMessage, setErrorMessage] = useState(null);
  const [showPassword, setShowPassword] = useState(false);
  //const prefix = "";
  const prefix = "/" + getSubDomainName();
  const imagePath = prefix + "/images/carousel-dot.svg";
  const addRemoveBodyOverFlowClass = (mode) => {
    const body = $(document.body);
    const cls = "overflow-hidden";
    if (mode === true) {
      if (body.hasClass(cls) === false) {
        body.addClass(cls);
      }
    } else {
      body.removeClass(cls);
    }
  };

  const modalWrapperResetPasswordClassName = "modal-wrapper.reset-password";
  const errorMessageClassName = "error-message";
  let errorField = "." + modalWrapperResetPasswordClassName + " ";
  errorField += "." + errorMessageClassName;
  const selectors = {
    FormBlockWrapper: ".form-block-wrapper",
    PasswordField: ".password-field",
    ConfirmPasswordField: ".confirm-password-field",
    ShowPasswordCheckbox: "#showPasswordCheckbox",
    ResetPasswordButton: ".reset-password-button",
    Form: "#email-form",
    ErrorField: errorField,
    PasswordStrengthField: ".password-strength",
  };

  const triState = {
    Valid: 0,
    Invalid: 1,
    Empty: 2,
  };

  const cSS = {
    LI: {
      Valid: "valid",
      Invalid: "invalid",
    },
    IMG: {
      Valid: "valid-checkmark",
      Invalid: "invalid-checkmark",
      None: "password-strength-bullet-point",
    },
  };

  const handleChange = (element1, element2) => {
    const passwordValue = $(element1).val();
    const confirmPasswordValue = $(element2).val();
    const validateLength = () => {
      if (passwordValue.length === 0) {
        return triState.Empty;
      }
      if (passwordValue.length >= 8 && passwordValue.length <= 12) {
        return triState.Valid;
      }
      return triState.Invalid;
    };
    const validateNumber = () => {
      let stateValue = triState.Empty;
      const arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
      if (passwordValue.length > 0) {
        stateValue = triState.Invalid;
        for (let c = 0; c < arr.length; c++) {
          if (passwordValue.includes(arr[c].toString())) {
            stateValue = triState.Valid;
            break;
          }
        }
      }
      return stateValue;
    };
    const validateSpecialCharacter = () => {
      let stateValue = triState.Empty;
      const arr = [
        "@",
        "#",
        "$",
        "^",
        "~",
        "`",
        "!",
        "%",
        "&",
        "*",
        "(",
        ")",
        "{",
        "}",
        "[",
        "]",
        ":",
        ";",
        '"',
        "<",
        ">",
        "?",
        "/",
        "|",
        "\\",
        "+",
        "=",
        "-",
        "_",
        "'",
        ",",
        ".",
      ];
      if (passwordValue.length > 0) {
        stateValue = triState.Invalid;
        for (let c = 0; c < arr.length; c++) {
          if (passwordValue.includes(arr[c].toString())) {
            stateValue = triState.Valid;
            break;
          }
        }
      }

      return stateValue;
    };
    const validateRestrictedCharacter = () => {
      return triState.Valid;
    };
    const validateUpperLowerCaseCharacters = () => {
      let stateValue1 = triState.Empty;
      let stateValue2 = triState.Empty;
      const arr = [
        "A",
        "B",
        "C",
        "D",
        "E",
        "F",
        "G",
        "H",
        "I",
        "J",
        "K",
        "L",
        "M",
        "N",
        "O",
        "P",
        "Q",
        "R",
        "S",
        "T",
        "U",
        "V",
        "W",
        "X",
        "Y",
        "Z",
      ];
      if (passwordValue.length > 0) {
        stateValue1 = triState.Invalid;
        stateValue2 = triState.Invalid;
        for (let c = 0; c < arr.length; c++) {
          if (passwordValue.includes(arr[c].toString())) {
            stateValue1 = triState.Valid;
            break;
          }
        }
        for (let c = 0; c < arr.length; c++) {
          if (passwordValue.includes(arr[c].toString().toLowerCase())) {
            stateValue2 = triState.Valid;
            break;
          }
        }
      }
      if (stateValue1 === stateValue2) {
        return stateValue1;
      }
      return triState.Invalid;
    };
    const validateMatch = () => {
      if (passwordValue.length > 0) {
        if (passwordValue !== confirmPasswordValue) {
          return triState.Invalid;
        }
        return triState.Valid;
      }
      return triState.Empty;
    };
    const lengthValidationResult = validateLength();
    const numberValidationResult = validateNumber();
    const specialCharacterValidationResult = validateSpecialCharacter();
    const restrictedCharacterValidationResult = validateRestrictedCharacter();
    const upperLowerCaseCharactersValidationResult =
      validateUpperLowerCaseCharacters();
    const matchResult = validateMatch();

    let parent = $(selectors.PasswordStrengthField);
    const liSelectors = [
      "chars",
      "letters",
      "special",
      "restricted",
      "digits",
      "match",
    ];
    const values = [
      lengthValidationResult,
      upperLowerCaseCharactersValidationResult,
      specialCharacterValidationResult,
      restrictedCharacterValidationResult,
      numberValidationResult,
      matchResult,
    ];

    let results = [];
    for (let s = 0; s < liSelectors.length; s++) {
      let sSelector = $(parent).find("li." + liSelectors[s]);
      let img = sSelector.find("img");

      sSelector.removeClass(cSS.LI.Valid).removeClass(cSS.LI.Invalid);
      img
        .removeClass(cSS.IMG.Valid)
        .removeClass(cSS.IMG.Invalid)
        .removeClass(cSS.IMG.None)
        .attr("src", "");
      const result = values[s];
      results.push(result);
      switch (result) {
        case triState.Valid: {
          sSelector.addClass(cSS.LI.Valid);
          img.addClass(cSS.IMG.Valid);
          img.attr("src", prefix + "/images/checkmark-green.png");
          break;
        }
        case triState.Invalid: {
          sSelector.addClass(cSS.LI.Invalid);
          img.addClass(cSS.IMG.Invalid);
          img.attr("src", prefix + "/images/not-valid-selection.png");
          break;
        }
        case triState.Empty:
        default: {
          img.addClass(cSS.IMG.None);
          img.attr("src", imagePath);
          break;
        }
      }
    }
    if (results.indexOf(triState.Invalid) > -1) {
      return triState.Invalid;
    }
    if (results.indexOf(triState.Empty) > -1) {
      return triState.Empty;
    }
    return triState.Valid;
  };

  const handleOnChangePassword = async (event) => {
    let email = null;
    let isSelf = true;
    const validationResult = handleChange(
      selectors.PasswordField,
      selectors.ConfirmPasswordField
    );
    if (validationResult === triState.Valid) {
      setShowError(false);
      setErrorMessage(null);
      setProcessing(true);
      let isAllowed = true;
      if (props.email !== undefined && props.email !== null) {
        email = props.email;
        isSelf = false;
      } else {
        const loginUserType = state?.user?.userProfile?.loginUserType
          .toString()
          .toUpperCase();
        isAllowed =
          loginUserType === "BREAKGLASS" || loginUserType === "FRMUSER";
        email = state?.user?.userProfile?.email;
      }

      if (isAllowed) {
        if (props.updateLoaderStatus !== undefined) {
          props.updateLoaderStatus(true);
        }
        const payload = {
          NewPassword: $(selectors.PasswordField).val(),
          Email: email,
          IsPasswordAutoGenerated: false,
        };
        await ResetPassword(payload).then(
          (response) => {
            if (response.length === 0) {
              addRemoveBodyOverFlowClass(false);
              setProcessing(false);
              props.callOpen(false);
              if (props.updateLoaderStatus !== undefined) {
                props.updateLoaderStatus(false);
              }
              showMessage("Password changed successfully", 2, "");
              if (isSelf === false) {
                props.navigateToGrid();
              }
            } else {
              setShowError(true);
              setProcessing(false);
              setErrorMessage("Error while changing password");
              if (props.updateLoaderStatus !== undefined) {
                props.updateLoaderStatus(false);
              }
            }
          },
          (err) => {
            setShowError(true);
            setErrorMessage("Invalid password");
            if (props.updateLoaderStatus !== undefined) {
              props.updateLoaderStatus(false);
            }
            setProcessing(false);
          }
        );
      } else {
        setShowError(true);
        setErrorMessage("Change password not allowed");
        setProcessing(false);
      }
    } else {
      setShowError(true);
      setErrorMessage("Please follow the password rules as mentioned above");
      setProcessing(false);
      if (props.updateLoaderStatus !== undefined) {
        props.updateLoaderStatus(false);
      }
    }
  };

  const handleClose = (e) => {
    props.callOpen(false);
    e.preventDefault();
  };

  const getErrorClassVariable = () => {
    const mainClassName = "error-message";
    if (showError === false) {
      return mainClassName + " hide";
    }
    return mainClassName;
  };

  const triggerChange = (c) => {
    const result = handleChange(
      selectors.PasswordField,
      selectors.ConfirmPasswordField
    );
    if (c === 0) {
      const attrName = "disabled";
      const val = $(selectors.PasswordField).val();
      if (val && val.length > 0) {
        $(selectors.ConfirmPasswordField).removeAttr(attrName);
      } else {
        $(selectors.ConfirmPasswordField).attr(attrName, attrName);
      }
    } else {
      if (result === triState.Valid) {
        setShowError(false);
        setErrorMessage(null);
      }
    }
  };

  const onFormKeyInput = (event) => {
    if (event.which === 13) {
      handleOnChangePassword(event);
    }
  };

  const showHidePasswordFields = (event) => {
    setShowPassword(!showPassword);
  };

  const getMainClassName = () => {
    let cls = "modal-wrapper";

    if (props.open === true) {
      cls += " show-modal-wrapper";
    }
    cls += " reset-password";
    return cls;
  };

  return (
    <>
      <div className={getMainClassName()}>
        <div className="modal-block">
          <div className="confirmation-content-wrapper">
            <div className="partial-container">
              <div className="login-block-form w-form">
                <form
                  id="email-form"
                  name="email-form"
                  data-name="Email Form"
                  className="login-form-2"
                  onKeyUp={(event) => {
                    onFormKeyInput(event);
                  }}
                >
                  <div className="form-block-wrapper">
                    <div className="form-section-title small">
                      Change password
                    </div>
                    <div>
                      <label className="field-label">New Password</label>
                      <input
                        type={showPassword ? "text" : "password"}
                        className="input-field w-input password-field"
                        maxLength="12"
                        name="New-password"
                        data-name="New-password"
                        placeholder=""
                        required
                        onInput={() => {
                          triggerChange(0);
                        }}
                        onPaste={() => {
                          triggerChange(0);
                        }}
                        onChange={() => {
                          triggerChange(0);
                        }}
                        onFocus={() => {
                          triggerChange(0);
                        }}
                      ></input>
                      <label className="field-label">
                        Confirm New Password
                      </label>
                      <input
                        disabled
                        type={showPassword ? "text" : "password"}
                        className="input-field w-input confirm-password-field"
                        maxLength="12"
                        name="confirm-new-password"
                        data-name="confirm-new-password"
                        placeholder=""
                        id="ConfirmPassword"
                        required
                        onInput={() => {
                          triggerChange(1);
                        }}
                        onPaste={() => {
                          triggerChange(1);
                        }}
                        onChange={() => {
                          triggerChange(1);
                        }}
                        onFocus={() => {
                          triggerChange(1);
                        }}
                      ></input>
                      <div className="show-password-block">
                        <input
                          type="checkbox"
                          id="showPasswordCheckbox"
                          onClick={(event) => {
                            showHidePasswordFields(event);
                          }}
                        ></input>
                        <label>Show Password</label>
                      </div>
                    </div>

                    <div className="password-strength">
                      <div className="h6-style-guide">
                        Password must include the following:
                      </div>
                      <div className="form-group">
                        <ul
                          className="conditions"
                          role="presentation"
                          aria-atomic="true"
                        >
                          <li className="chars">
                            <img
                              className="chars-checkmark password-strength-bullet-point"
                              src={imagePath}
                              aria-label="criteria met"
                            ></img>
                            <div className="conditions-text">
                              Use between 8 and 12 characters
                            </div>
                          </li>
                          <li className="letters">
                            <img
                              className="letters-checkmark password-strength-bullet-point"
                              src={imagePath}
                              aria-label="criteria not met"
                            ></img>
                            <div className="conditions-text">
                              Include at least one lowercase (a-z) and one
                              uppercase letter (A-Z)
                            </div>
                          </li>
                          <li className="special">
                            <img
                              className="special-checkmark password-strength-bullet-point"
                              src={imagePath}
                              aria-label="criteria not met"
                            ></img>
                            <div className="conditions-text special-text">
                              Include at least one special character e.g. $#@^"
                            </div>
                          </li>

                          <li className="digits">
                            <img
                              className="digits-checkmark password-strength-bullet-point"
                              src={imagePath}
                              aria-label="criteria not met"
                            ></img>
                            <div className="conditions-text">
                              Include at least one digit (0-9)
                            </div>
                          </li>
                          <li className="match">
                            <img
                              className="match-checkmark password-strength-bullet-point"
                              src={imagePath}
                              aria-label="criteria not met"
                            ></img>
                            <div className="conditions-text">
                              Passwords match
                            </div>
                          </li>
                        </ul>
                      </div>
                    </div>
                    <div className={getErrorClassVariable()}>
                      <span>{errorMessage}</span>
                    </div>
                  </div>
                </form>
              </div>
            </div>
          </div>
          <div className="confirmation-button-block">
            <button
              className="confirmation-button w-button yes"
              disabled={processing}
              onClick={(event) => {
                handleOnChangePassword(event);
              }}
            >
              Submit
            </button>

            <button
              className="confirmation-button w-button no"
              onClick={(event) => {
                handleClose(event);
              }}
            >
              Cancel
            </button>
          </div>
        </div>
      </div>
    </>
  );
};
